package com.bbcare.followup.plat.service.impl;


import com.bbcare.comm.*;
import com.bbcare.followup.plat.entity.*;
import com.bbcare.followup.plat.service.IExtendService;
import com.bbcare.followup.plat.store.ibatis.*;
import com.bbcare.treat.plat.store.ibatis.IPtFuQueueDAO;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.exceptions.JedisConnectionException;

import javax.annotation.Resource;
import java.text.ParseException;
import java.util.*;

@Service
public class ExtendService implements IExtendService {
    private final Log logger = LogFactory.getLog(PatientService.class);

    @Resource(name = "jedisPool")
    private JedisPool jedisPool;

    @Autowired
    private IPatientTaskDAO patientTaskDao;

    @Autowired
    private IPatientTaskContentDAO patientTaskConDao;

    @Autowired
    private IPatientQueueSchemeDAO patientQueueSchemeDao;

    @Autowired
    private IPatientOperationRecordDAO patientOperationRecordDao;

    @Autowired
    private IPatientDAO patientDao;

    @Autowired
    private IConfCacheDAO confCacheDao;

    @Autowired
    private IFollowTaskExtendDAO followTaskExtendDAO;

    @Autowired
    private IFollowTaskContentDAO followTaskContDao;

    @Autowired
    private IContentTemplDAO contentTemplDao;


    private String getTaskName(String expectedDay,String executeTime) throws ParseException {
       return ToolUtils.getAgeMonDayByDate3(expectedDay,executeTime);
    }

    private Boolean isExecute(String executeType) {
        String  executeTypeString = PropertiesUtils.getProperty("executeTypeString");
        if(StringUtils.isNotEmpty(executeType) && StringUtils.isNotEmpty(executeTypeString) && (Arrays.asList(executeTypeString.split(",")).contains(executeType))) {
            return true;
        } else {
            return false;
        }
    }


    @Override
    public void patientTaskNameModify(Map nextTaskMapIn, Patient patient, PatientTask patientTask) {
        //判断是否需要修改
                  if(!isExecute(patientTask.getExecuteType())) {
                      return;
                  };
            String TaskName =  patientTask.getTaskName();
            try{
                Integer day  =  DateUtil.daysBetweenDateStr(  patient.getExpectedDay(),nextTaskMapIn.get("executeTime").toString());

                if(TaskName.contains("周")){
                    Integer week = day/7+1;
                    TaskName=TaskName.replaceAll("\\d", week.toString());
                    nextTaskMapIn.put("TaskName",TaskName);
                    return;
                }
                if(TaskName.contains("月")){
                    Integer month = day/30+1;
                    TaskName=TaskName.replaceAll("\\d", month.toString());
                    nextTaskMapIn.put("TaskName",TaskName);
                    return;
                }
                if(TaskName.contains("年")){
                    Integer year = day/365+1;
                    TaskName=TaskName.replaceAll("\\d", year.toString());
                    nextTaskMapIn.put("TaskName",TaskName);
                    return;
                }
            }catch (Exception ex){
                logger.error("修改下一节点任务名称失败"+ex.getMessage());
            }




    }

    @Override
    public void addNewPatientTask(Map paramMap) throws Exception {


        // oprInfo
        // taskInfo
        String taskId = (String) paramMap.get("taskId");


        // 查询当前任务信息
        Map<String, Object> taskMapIn = new HashMap<String, Object>();
        taskMapIn.put("taskId", taskId);
        List<PatientTask> ptVoList = patientTaskDao.selectById(taskMapIn);
        if (CollectionUtils.isEmpty(ptVoList)) {
            throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_TASK_NOT_EXIST, "该患者当前任务不存在！");
        }
        PatientTask currTaskVo = ptVoList.get(0);
        if(!isExecute(currTaskVo.getExecuteType())){
            return;
        }

        Map<String, Object> qryMap = new HashMap<String, Object>();
        String userId = (String)paramMap.get("userId");
        qryMap.put("userId",userId);
        Patient patient =  patientDao.selectById(qryMap);
        Map<String, Object> argMap = new HashMap<String, Object>();
        String nextExecuteTime = (String) paramMap.get("nextDate");
        String queueId = (String) paramMap.get("queueId");
        String tenantId = (String) paramMap.get("tenantId");

        int day = DateUtil.daysBetweenStr(patient.getExpectedDay(),nextExecuteTime);
        argMap.put("day",day);
        argMap.put("queueId",queueId);
        argMap.put("tenantId",tenantId);
        String ptk_id = SeqUtil.getSeqNo(Constants.SEQ_NO_FOR_PTTASKID);
        String currDay = DateUtil.getCurrDate();
        String authorName = (String) paramMap.get("authorName");
        String authorId = (String) paramMap.get("authorId");
        String updateAccept = SeqUtil.getSeqNo();
        String opCode = "1018";
        String opType = "2";
        String opNote = "最后一个任务，根据下次随访时间，添加随访任务";
        // 更新当前任务的next_task_id为新生成的任务id
        List<FollowTaskExtend> list = followTaskExtendDAO.selectByDay(argMap);
        List<PatientTask> ptTaskList = new ArrayList<PatientTask>();
        List<PatientTaskContent> ptTaskContentList = new ArrayList<PatientTaskContent>();
        if(list.size()>0){//有配置任务,从模板中取出
            for ( FollowTaskExtend taskExtend: list) {
                PatientTask ptk = new PatientTask();
                ptk.setId(ptk_id);
                if (StringUtils.isEmpty(patient.getExpectedDay())) {// 微信产妇建档 可能没有生日选项
                    throw new AppException("",
                            "缺少预产期，请完善资料后再次尝试！");
                }

                ptk.setTaskStatus(Constants.PATIENT_TASK_STATUS_INIT);
                ptk.setAuthorId(authorId);
                ptk.setExecuteTime(nextExecuteTime);
                ptk.setBeginTime(DateUtil.calcDay(nextExecuteTime, "-", taskExtend.getWindowDay()));
                ptk.setEndTime(DateUtil.calcDay(nextExecuteTime, "+", taskExtend.getWindowDay()));
                ptk.setCreateTime(currDay);
                ptk.setExecuteDay(taskExtend.getExecuteDay());
                ptk.setExecuteType(taskExtend.getExecuteType());
                ptk.setInformFlag(taskExtend.getInformFlag());
                ptk.setPtSchemeid(currTaskVo.getPtSchemeid());
                ptk.setSeqNo(currTaskVo.getSeqNo() + 1);
                ptk.setTaskIntro(taskExtend.getTaskIntro());
                ptk.setTaskName(getTaskName(patient.getExpectedDay(),nextExecuteTime));
                ptk.setUpdateTime(currDay);
                ptk.setUserId(patient.getId());
                ptk.setWarnDay(taskExtend.getWarnDay());
                ptk.setWindowDay(taskExtend.getWindowDay());
                ptk.setQueueId(queueId);
                ptk.setUpdateAccept(updateAccept);
                if (!StringUtils.isBlank(taskExtend.getTaskType())) {
                    ptk.setTaskType(taskExtend.getTaskType());// 方案中任务
                } else {
                    ptk.setTaskType(Constants.TASK_TYPE_SCHEME_SCHEDULE);// 门诊任务
                }
                ptTaskList.add(ptk);
                HashMap<String, Object> taskContentParam = new HashMap<String, Object>();
                taskContentParam.put("taskId", taskExtend.getId());
                taskContentParam.put("schemeVersionid",taskExtend.getSchemeVersionid());
                List<FollowTaskContent> taskContList = followTaskContDao.selectByTaskId(taskContentParam);
                if (null == taskContList || 0 == taskContList.size()) {
                    continue;
                }
                FollowTaskContent ftc = new FollowTaskContent();
                int tc = 0;
                for (; tc < taskContList.size(); tc++) {
                    ftc = taskContList.get(tc);

                    Map<String, Object> templMap = new HashMap<String, Object>();
                    templMap.put("id", ftc.getTemplId());
                    List<ContentTempl> ctList = contentTemplDao.selectTemplById(templMap);
                    if (null == ctList || 0 == ctList.size()) {
                        throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_QUES_TEMPL_NOT_EXIST, "查询任务内容模板记录为空！");
        }
                    ContentTempl conVo = ctList.get(0);
                    HashMap<String, Object> contVerMap = new HashMap<String, Object>();
                    contVerMap.put("templId", ftc.getTemplId());
                    contVerMap.put("templVersion", ftc.getTemplVersion());
                    List<ContentTemplVersion> ctvList = contentTemplDao.selectContentDataNoTextByTempl(contVerMap);
                    if (null == ctvList || 0 == ctvList.size()) {
                        throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_QUES_TEMPLVERSION_NOT_EXIST,
                                "查询任务内容模板版本记录为空！");
                    }
                    ContentTemplVersion ctv = ctvList.get(0);
                    String ptkc_id = SeqUtil.getSeqNo(Constants.SEQ_NO_FOR_PTTASK_CONTID);
                    PatientTaskContent ptc = new PatientTaskContent();
                    ptc.setCreateTime(currDay);
                    ptc.setUpdateTime(currDay);
                    ptc.setId(ptkc_id);
                    ptc.setTaskId(ptk_id);
                    ptc.setTemplVersionid(ctv.getId());
                    ptc.setUpdateAccept(updateAccept);
                    ptc.setTemplType(conVo.getTemplType());
                    ptc.setUserId(userId);
                    ptc.setPtSchemeid(currTaskVo.getPtSchemeid());
                    ptc.setSeqNo(conVo.getSeqNo());
                    ptTaskContentList.add(ptc);
                }
            }
            patientTaskDao.savePatientTaskBatch(ptTaskList);
            if (ptTaskContentList.size() > 0) {
                patientTaskConDao.savePatientTaskContentBatch(ptTaskContentList);
            }


        }else{
        // 新增任务
        PatientTask tmpPtkVo = new PatientTask();
        tmpPtkVo.setId(ptk_id);
        tmpPtkVo.setTaskStatus(Constants.PATIENT_TASK_STATUS_INIT);
        tmpPtkVo.setAuthorId(authorId);
        tmpPtkVo.setExecuteTime(nextExecuteTime);
        tmpPtkVo.setBeginTime( DateUtil.calcDay(nextExecuteTime, "-",currTaskVo.getWindowDay() ));
        tmpPtkVo.setEndTime( DateUtil.calcDay(nextExecuteTime, "+",currTaskVo.getWindowDay() ));
        tmpPtkVo.setCreateTime(currDay);
        tmpPtkVo.setExecuteDay(currTaskVo.getExecuteDay());
        tmpPtkVo.setExecuteType(currTaskVo.getExecuteType());
        tmpPtkVo.setInformFlag(currTaskVo.getInformFlag());
        tmpPtkVo.setPtSchemeid(currTaskVo.getPtSchemeid());
        tmpPtkVo.setSeqNo(currTaskVo.getSeqNo() + 1);
        tmpPtkVo.setTaskIntro("根据下次随访节点自动创建随访任务");
        tmpPtkVo.setTaskName(getTaskName(patient.getExpectedDay(),nextExecuteTime));
        tmpPtkVo.setUpdateTime(currDay);
        tmpPtkVo.setUserId(currTaskVo.getUserId());
        tmpPtkVo.setWarnDay(3);
        tmpPtkVo.setWindowDay(7);
        tmpPtkVo.setQueueId(queueId);
        tmpPtkVo.setUpdateAccept(updateAccept);
        tmpPtkVo.setTaskType(currTaskVo.getTaskType());
        tmpPtkVo.setAuditStatus(Constants.PATIENT_TASK_AUDIT_STATUS_INIT);// 初始化审核状态
        tmpPtkVo.setTemporaryTask(currTaskVo.getTemporaryTask());
        patientTaskDao.save(tmpPtkVo);

        // 入任务历史表
        Map<String, Object> taskMap = new HashMap<String, Object>();
        // 新增任务内容
        taskMap.put("taskId", currTaskVo.getId());
        List<PatientTaskContent> refPtTaskCntList = patientTaskConDao.selectContentByTaskId(taskMap);
        if (!CollectionUtils.isEmpty(refPtTaskCntList)) {

            int cntSize = refPtTaskCntList.size();
            int kk = 0;
            for (kk = 0; kk < cntSize; kk++) {
                PatientTaskContent refPtcVo = refPtTaskCntList.get(kk);
                PatientTaskContent ptc = new PatientTaskContent();
                ptc.setCreateTime(currDay);
                ptc.setUpdateTime(currDay);
                ptc.setId(SeqUtil.getSeqNo(Constants.SEQ_NO_FOR_PTTASK_CONTID));
                ptc.setTaskId(ptk_id);
                ptc.setTemplVersionid(refPtcVo.getTemplVersionid());
                ptc.setUpdateAccept(updateAccept);
                ptc.setTemplType(refPtcVo.getTemplType());
                ptc.setUserId(refPtcVo.getUserId());
                ptc.setPtSchemeid(refPtcVo.getPtSchemeid());
                ptc.setSeqNo(refPtcVo.getSeqNo());

                ptTaskContentList.add(ptc);
            }
            if (ptTaskContentList.size() > 0) {
                patientTaskConDao.savePatientTaskContentBatch(ptTaskContentList);
            }
        }

        }
        Map<String, Object> taskMap = new HashMap<String, Object>();
        taskMap.put("taskId", taskId);
        taskMap.put("updateType", Constants.UPDATE_TYPE_UPDATE_X);
        taskMap.put("updateTime", currDay);
        taskMap.put("updateAccept", updateAccept);
        taskMap.put("nextTaskId", ptk_id);
        int upret = patientTaskDao.updatePatientTaskById(taskMap);
        if (0 == upret) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_PATIENT_TASK_NOT_EXIST, "患者当前任务不存在！"));
        }
        patientTaskDao.insertPatientTaskHisById(taskMap);
        taskMap.clear();
        // 更新队列实例记录，总任务数加1
        Map<String, Object> ptQueueMap = new HashMap<String, Object>();
        ptQueueMap.put("updateType", Constants.UPDATE_TYPE_UPDATE_X);
        ptQueueMap.put("updateTime", currDay);
        ptQueueMap.put("updateAccept", updateAccept);
        ptQueueMap.put("id", currTaskVo.getPtSchemeid());
        ptQueueMap.put("updateAuthor", authorId);
        ptQueueMap.put("totalNumIncr", "1");
        upret = patientQueueSchemeDao.updatePtQueueSchemeRecord(ptQueueMap);
        if (0 == upret) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_PATIENT_QUEUE_NOT_EXIST, "患者队列实例无记录！"));
        }
        patientQueueSchemeDao.insertPatientQueueSchemeHis(ptQueueMap);

        taskMap.clear();
        taskMap.put("taskId", ptk_id);
        taskMap.put("updateType", Constants.UPDATE_TYPE_INSERT);
        taskMap.put("updateTime", currDay);
        taskMap.put("updateAccept", updateAccept);
        patientTaskDao.insertPatientTaskHisById(taskMap);


        // 入操作流水记录表 ia_operation_record
        Map<String, Object> paramRecord = new HashMap<String, Object>();
        paramRecord.put("userName",patient.getUserName());
        paramRecord.put("userId", userId);
        paramRecord.put("queueId", queueId);
        paramRecord.put("authorId", authorId);
        paramRecord.put("opTime", currDay);
        if (Constants.OP_TYPE_SELF.equals(opType)) {
            paramRecord.put("type", Constants.PATIENT_ACTIVE_BUSI_TYPE_8);
        } else {
            paramRecord.put("type", Constants.PATIENT_ACTIVE_BUSI_TYPE_9);
        }
        if (Constants.OP_TYPE_SELF.equals(opType)) {
            paramRecord.put("opUsertype", Constants.OPCODE_TYPE_PATIENT);
        } else {
            paramRecord.put("opUsertype", Constants.OPCODE_TYPE_DOCTOR);
        }
        paramRecord.put("authorName", authorName);
        paramRecord.put("opCode", opCode);
        paramRecord.put("updateAccept", updateAccept);
        paramRecord.put("tenantId", tenantId);
        paramRecord.put("remark", opNote);
        paramRecord.put("opType", opType);
        paramRecord.put("taskId", ptk_id);
        Map<String, Object> outRecord = this.buildOperationRecord(paramRecord);
        patientOperationRecordDao.saveOperationRecord(outRecord);




    }


    public Map<String, Object> buildOperationRecord(Map<String, Object> paramMap) throws Exception {
        // 增加操作记录
        Map<String, Object> paramRecord = new HashMap<String, Object>();
        Calendar now = Calendar.getInstance();
        String month = String.valueOf(now.get(Calendar.MONTH) + 1);
        String day = String.valueOf(now.get(Calendar.DAY_OF_MONTH));
        Object opCode = paramMap.get("opCode");

        List<String> inList = new ArrayList<String>();
        String descStr = "";
        String remarkStr = (String) paramMap.get("remark");
        if (org.springframework.util.StringUtils.isEmpty(remarkStr)) {
            Jedis jedis = null;
            try {
                jedis = jedisPool.getResource();
                jedis.select(Constants.REDIS_DB_INDEX_CONFIG);

                inList.clear();
                inList.add(Constants.CONFIG_BS_STATIC_PARAM_PREFIX_PN);
                inList.add((String) opCode);
                inList.add(Constants.BUSI_OP_CODE_TYPE);
                String strKey = ToolUtils.assembleKey(inList);
                remarkStr = jedis.get(strKey);
                String paramValue = "";
                if (null == remarkStr) {
                    Map<String, Object> inMap = new HashMap<String, Object>();
                    inMap.put("type", Constants.BUSI_OP_CODE_TYPE);
                    inMap.put("paramCode", opCode);
                    List<Map<String, Object>> outList = confCacheDao.selectBsStaticParamByTypeAndCode(inMap);
                    if (null == outList || 0 == outList.size()) {
                        throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_STATIC_OPCODE_NOT_EXIST, "操作编码未配置!"));
                    }
                    Map<String, Object> outMap = outList.get(0);
                    remarkStr = (String) outMap.get("PARAM_NAME");
                    jedis.set(strKey, remarkStr);

                    inList.clear();
                    inList.add(Constants.CONFIG_BS_STATIC_PARAM_PREFIX_PV);
                    inList.add((String) opCode);
                    inList.add(Constants.BUSI_OP_CODE_TYPE);
                    String paramkey = ToolUtils.assembleKey(inList);
                    paramValue = (String) outMap.get("PARAM_VALUE");
                    jedis.set(paramkey, paramValue);
                }

                StringBuilder desc = new StringBuilder();
                if (Constants.OPCODE_TYPE_DOCTOR.equals(paramMap.get("opUsertype"))) {
                    desc.append("医生");
                    desc.append(paramMap.get("authorName"));
                    desc.append("为患者");
                    desc.append(paramMap.get("userName"));
                } else if (Constants.OPCODE_TYPE_PATIENT.equals(paramMap.get("opUsertype"))) {
                    desc.append("患者");
                    desc.append(paramMap.get("userName"));
                }
                desc.append(paramValue);
                descStr = desc.toString();
            } catch (JedisConnectionException jex) {
                logger.error("redis连接异常..." + jex.getMessage());
                throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_REDIS_CONNECT_ERROR, "Redis缓存连接失败!"));
            } finally {
                if (null != jedis) {
                    try {
                        jedis.close();
                        logger.warn("close redis connection...");
                    } catch (Exception ex) {
                        ex.printStackTrace();
                        throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_REDIS_CONNECT_CLOSE_FAILED,
                                "Redis缓存关闭失败!"));
                    }
                }
            }
        } else {
            descStr = remarkStr;
        }

        paramRecord.put("month", month);
        paramRecord.put("day", day);
        paramRecord.put("userId", paramMap.get("userId"));
        paramRecord.put("queueId", paramMap.get("queueId"));// 前端传入 还是自己去查
        paramRecord.put("opUser", paramMap.get("authorId"));
        paramRecord.put("opTime", paramMap.get("opTime"));
        paramRecord.put("remark", remarkStr);
        paramRecord.put("busiCategory", paramMap.get("type"));
        paramRecord.put("opUsertype", paramMap.get("opUsertype"));
        paramRecord.put("id", paramMap.get("updateAccept"));
        paramRecord.put("opDesc", descStr);
        paramRecord.put("opCode", opCode);
        paramRecord.put("busiId", paramMap.get("busiId"));
        paramRecord.put("tenantId", paramMap.get("tenantId"));
        paramRecord.put("opType", paramMap.get("opType"));
        paramRecord.put("taskId", paramMap.get("taskId"));
        paramRecord.put("breifIntro", paramMap.get("breifIntro"));

        return paramRecord;
    }
}
